// Package cmn provides common constants, types, and utilities for AIS clients
// and AIStore.
/*
 * Copyright (c) 2018-2025, NVIDIA CORPORATION. All rights reserved.
 */
package cos

import (
	"errors"
	"io"
	"os"
	"syscall"

	"github.com/NVIDIA/aistore/cmn/debug"
	"github.com/NVIDIA/aistore/cmn/nlog"
)

var ioErrs = [...]error{
	io.ErrShortWrite,

	syscall.EIO,       // I/O error
	syscall.ENOTDIR,   // mountpath is missing
	syscall.EBUSY,     // device or resource is busy
	syscall.ENXIO,     // no such device
	syscall.EBADF,     // bad file number
	syscall.EBADFD,    // file descriptor in bad state
	syscall.ENODEV,    // no such device
	syscall.EUCLEAN,   // (mkdir)structure needs cleaning = broken filesystem
	syscall.EROFS,     // readonly filesystem
	syscall.EDQUOT,    // quota exceeded
	syscall.ESTALE,    // stale file handle
	syscall.ENOSPC,    // no space left
	syscall.ECANCELED, // operation canceled
}

// Checks if the error is generated by any IO operation and if the error
// is severe enough to run the FSHC for mountpath testing
func IsIOError(err error) bool {
	debug.Assert(err != nil)

	if IsErrMv(err) {
		return false
	}

	// via os.NewSyscallError(), with a prior check !os.IsNotExist()
	if e, ok := err.(*os.SyscallError); ok {
		nlog.Infoln("by syscall-error", e)
		return true
	}
	// assorted errnos, via errors.Is
	for _, e := range ioErrs {
		if errors.Is(err, e) {
			nlog.Infoln("by io-error", e)
			return true
		}
	}
	return false
}

func IsErrXattrNotFound(err error) bool {
	return errors.Is(err, syscall.ENODATA)
}
